import { prisma } from '@/lib/database'
import { cache } from '@/lib/redis'
import { 
  ValidationError, 
  NotFoundError, 
  AuthorizationError,
  ConflictError 
} from '@/middleware/errorHandler'

// 类型定义
export interface PendingPlugin {
  id: string
  name: string
  displayName: string
  description: string
  category: string
  developer: {
    username: string
    displayName: string
    email: string
    verified: boolean
  }
  latestVersion?: string
  repositoryUrl?: string
  homepageUrl?: string
  license?: string
  keywords: string[]
  tags: string[]
  createdAt: Date
  updatedAt: Date
}

export interface SystemStats {
  overview: {
    totalPlugins: number
    totalDevelopers: number
    totalDownloads: number
    pendingReviews: number
  }
  plugins: {
    approved: number
    pending: number
    rejected: number
    suspended: number
  }
  developers: {
    active: number
    suspended: number
    verified: number
  }
  activity: {
    newPluginsThisWeek: number
    newDevelopersThisWeek: number
    downloadsThisWeek: number
  }
}

export interface UserManagement {
  id: string
  username: string
  email: string
  displayName?: string
  role: string
  status: string
  verified: boolean
  emailVerified: boolean
  pluginCount: number
  totalDownloads: number
  lastLoginAt?: Date
  createdAt: Date
}

export interface AuditLogEntry {
  id: string
  action: string
  resourceType?: string
  resourceId?: string
  oldValues?: any
  newValues?: any
  ipAddress?: string
  userAgent?: string
  user?: {
    username: string
    email: string
  }
  createdAt: Date
}

export class AdminService {
  // 获取待审核插件列表
  async getPendingPlugins(page = 1, limit = 20): Promise<{
    plugins: PendingPlugin[]
    pagination: { page: number; limit: number; total: number; totalPages: number }
  }> {
    const offset = (page - 1) * limit

    const [plugins, total] = await Promise.all([
      prisma.plugin.findMany({
        where: { status: 'pending' },
        include: {
          developer: {
            select: {
              username: true,
              displayName: true,
              email: true,
              verified: true
            }
          }
        },
        orderBy: { createdAt: 'asc' }, // 最早提交的优先审核
        skip: offset,
        take: limit
      }),
      prisma.plugin.count({
        where: { status: 'pending' }
      })
    ])

    const formattedPlugins: PendingPlugin[] = plugins.map(plugin => ({
      id: plugin.id,
      name: plugin.name,
      displayName: plugin.displayName,
      description: plugin.description || '',
      category: plugin.category,
      developer: {
        username: plugin.developer.username,
        displayName: plugin.developer.displayName || '',
        email: plugin.developer.email,
        verified: plugin.developer.verified
      },
      latestVersion: plugin.lastVersion || undefined,
      repositoryUrl: plugin.repositoryUrl || undefined,
      homepageUrl: plugin.homepageUrl || undefined,
      license: plugin.license || undefined,
      keywords: plugin.keywords,
      tags: plugin.tags,
      createdAt: plugin.createdAt,
      updatedAt: plugin.updatedAt
    }))

    return {
      plugins: formattedPlugins,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit)
      }
    }
  }

  // 审核通过插件
  async approvePlugin(adminId: string, pluginId: string, reason?: string): Promise<void> {
    // 验证管理员权限
    await this.validateAdminPermission(adminId)

    // 查找插件
    const plugin = await prisma.plugin.findUnique({
      where: { id: pluginId },
      include: { developer: true }
    })

    if (!plugin) {
      throw new NotFoundError('Plugin not found')
    }

    if (plugin.status !== 'pending') {
      throw new ValidationError('Plugin is not in pending status')
    }

    // 更新插件状态
    await prisma.$transaction(async (tx) => {
      // 更新插件状态
      await tx.plugin.update({
        where: { id: pluginId },
        data: { 
          status: 'approved',
          updatedAt: new Date()
        }
      })

      // 记录审计日志
      await tx.auditLog.create({
        data: {
          userId: adminId,
          action: 'plugin_approved',
          resourceType: 'plugin',
          resourceId: pluginId,
          newValues: { 
            status: 'approved', 
            reason: reason || 'Plugin approved by admin'
          }
        }
      })
    })

    // 清除相关缓存
    await this.clearAdminCache()
  }

  // 拒绝插件
  async rejectPlugin(adminId: string, pluginId: string, reason: string): Promise<void> {
    // 验证管理员权限
    await this.validateAdminPermission(adminId)

    if (!reason || reason.trim().length < 10) {
      throw new ValidationError('Rejection reason must be at least 10 characters long')
    }

    // 查找插件
    const plugin = await prisma.plugin.findUnique({
      where: { id: pluginId },
      include: { developer: true }
    })

    if (!plugin) {
      throw new NotFoundError('Plugin not found')
    }

    if (plugin.status !== 'pending') {
      throw new ValidationError('Plugin is not in pending status')
    }

    // 更新插件状态
    await prisma.$transaction(async (tx) => {
      // 更新插件状态
      await tx.plugin.update({
        where: { id: pluginId },
        data: { 
          status: 'rejected',
          updatedAt: new Date()
        }
      })

      // 记录审计日志
      await tx.auditLog.create({
        data: {
          userId: adminId,
          action: 'plugin_rejected',
          resourceType: 'plugin',
          resourceId: pluginId,
          newValues: { 
            status: 'rejected', 
            reason: reason.trim()
          }
        }
      })
    })

    // 清除相关缓存
    await this.clearAdminCache()
  }

  // 暂停插件
  async suspendPlugin(adminId: string, pluginId: string, reason: string): Promise<void> {
    // 验证管理员权限
    await this.validateAdminPermission(adminId)

    if (!reason || reason.trim().length < 10) {
      throw new ValidationError('Suspension reason must be at least 10 characters long')
    }

    // 查找插件
    const plugin = await prisma.plugin.findUnique({
      where: { id: pluginId }
    })

    if (!plugin) {
      throw new NotFoundError('Plugin not found')
    }

    if (plugin.status === 'suspended') {
      throw new ConflictError('Plugin is already suspended')
    }

    // 更新插件状态
    await prisma.$transaction(async (tx) => {
      // 更新插件状态
      await tx.plugin.update({
        where: { id: pluginId },
        data: { 
          status: 'suspended',
          updatedAt: new Date()
        }
      })

      // 记录审计日志
      await tx.auditLog.create({
        data: {
          userId: adminId,
          action: 'plugin_suspended',
          resourceType: 'plugin',
          resourceId: pluginId,
          oldValues: { status: plugin.status },
          newValues: { 
            status: 'suspended', 
            reason: reason.trim()
          }
        }
      })
    })

    // 清除相关缓存
    await this.clearAdminCache()
  }

  // 恢复插件
  async restorePlugin(adminId: string, pluginId: string): Promise<void> {
    // 验证管理员权限
    await this.validateAdminPermission(adminId)

    // 查找插件
    const plugin = await prisma.plugin.findUnique({
      where: { id: pluginId }
    })

    if (!plugin) {
      throw new NotFoundError('Plugin not found')
    }

    if (plugin.status !== 'suspended') {
      throw new ValidationError('Plugin is not suspended')
    }

    // 更新插件状态
    await prisma.$transaction(async (tx) => {
      // 更新插件状态为已批准
      await tx.plugin.update({
        where: { id: pluginId },
        data: { 
          status: 'approved',
          updatedAt: new Date()
        }
      })

      // 记录审计日志
      await tx.auditLog.create({
        data: {
          userId: adminId,
          action: 'plugin_restored',
          resourceType: 'plugin',
          resourceId: pluginId,
          oldValues: { status: 'suspended' },
          newValues: { status: 'approved' }
        }
      })
    })

    // 清除相关缓存
    await this.clearAdminCache()
  }

  // 验证管理员权限
  private async validateAdminPermission(userId: string): Promise<void> {
    const user = await prisma.developer.findUnique({
      where: { id: userId },
      select: { role: true, status: true }
    })

    if (!user) {
      throw new NotFoundError('User not found')
    }

    if (user.role !== 'admin') {
      throw new AuthorizationError('Admin permission required')
    }

    if (user.status !== 'active') {
      throw new AuthorizationError('Admin account is not active')
    }
  }

  // 获取系统统计信息
  async getSystemStats(): Promise<SystemStats> {
    // 尝试从缓存获取
    const cacheKey = 'admin:stats'
    const cached = await cache.get(cacheKey)
    if (cached) {
      return JSON.parse(cached)
    }

    // 计算一周前的日期
    const oneWeekAgo = new Date()
    oneWeekAgo.setDate(oneWeekAgo.getDate() - 7)

    // 并行查询所有统计数据
    const [
      totalPlugins,
      totalDevelopers,
      totalDownloads,
      pendingReviews,
      approvedPlugins,
      pendingPlugins,
      rejectedPlugins,
      suspendedPlugins,
      activeDevelopers,
      suspendedDevelopers,
      verifiedDevelopers,
      newPluginsThisWeek,
      newDevelopersThisWeek,
      downloadsThisWeek
    ] = await Promise.all([
      // 总体统计
      prisma.plugin.count(),
      prisma.developer.count(),
      prisma.download.count(),
      prisma.plugin.count({ where: { status: 'pending' } }),

      // 插件状态统计
      prisma.plugin.count({ where: { status: 'approved' } }),
      prisma.plugin.count({ where: { status: 'pending' } }),
      prisma.plugin.count({ where: { status: 'rejected' } }),
      prisma.plugin.count({ where: { status: 'suspended' } }),

      // 开发者状态统计
      prisma.developer.count({ where: { status: 'active' } }),
      prisma.developer.count({ where: { status: 'suspended' } }),
      prisma.developer.count({ where: { verified: true } }),

      // 本周活动统计
      prisma.plugin.count({ where: { createdAt: { gte: oneWeekAgo } } }),
      prisma.developer.count({ where: { createdAt: { gte: oneWeekAgo } } }),
      prisma.download.count({ where: { downloadedAt: { gte: oneWeekAgo } } })
    ])

    const stats: SystemStats = {
      overview: {
        totalPlugins,
        totalDevelopers,
        totalDownloads,
        pendingReviews
      },
      plugins: {
        approved: approvedPlugins,
        pending: pendingPlugins,
        rejected: rejectedPlugins,
        suspended: suspendedPlugins
      },
      developers: {
        active: activeDevelopers,
        suspended: suspendedDevelopers,
        verified: verifiedDevelopers
      },
      activity: {
        newPluginsThisWeek,
        newDevelopersThisWeek,
        downloadsThisWeek
      }
    }

    // 缓存5分钟
    await cache.set(cacheKey, JSON.stringify(stats), 300)

    return stats
  }

  // 获取用户管理列表
  async getUsers(page = 1, limit = 20, filters?: {
    status?: string
    role?: string
    verified?: boolean
    search?: string
  }): Promise<{
    users: UserManagement[]
    pagination: { page: number; limit: number; total: number; totalPages: number }
  }> {
    const offset = (page - 1) * limit

    // 构建查询条件
    const where: any = {}

    if (filters?.status) {
      where.status = filters.status
    }

    if (filters?.role) {
      where.role = filters.role
    }

    if (filters?.verified !== undefined) {
      where.verified = filters.verified
    }

    if (filters?.search) {
      where.OR = [
        { username: { contains: filters.search, mode: 'insensitive' } },
        { email: { contains: filters.search, mode: 'insensitive' } },
        { displayName: { contains: filters.search, mode: 'insensitive' } }
      ]
    }

    const [users, total] = await Promise.all([
      prisma.developer.findMany({
        where,
        select: {
          id: true,
          username: true,
          email: true,
          displayName: true,
          role: true,
          status: true,
          verified: true,
          emailVerified: true,
          lastLoginAt: true,
          createdAt: true,
          _count: {
            select: {
              plugins: true
            }
          }
        },
        orderBy: { createdAt: 'desc' },
        skip: offset,
        take: limit
      }),
      prisma.developer.count({ where })
    ])

    const formattedUsers: UserManagement[] = users.map(user => ({
      id: user.id,
      username: user.username,
      email: user.email,
      displayName: user.displayName || undefined,
      role: user.role,
      status: user.status,
      verified: user.verified,
      emailVerified: user.emailVerified,
      pluginCount: user._count.plugins,
      totalDownloads: 0, // TODO: 计算用户插件的总下载量
      lastLoginAt: user.lastLoginAt || undefined,
      createdAt: user.createdAt
    }))

    return {
      users: formattedUsers,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit)
      }
    }
  }

  // 暂停用户
  async suspendUser(adminId: string, userId: string, reason: string): Promise<void> {
    // 验证管理员权限
    await this.validateAdminPermission(adminId)

    if (!reason || reason.trim().length < 10) {
      throw new ValidationError('Suspension reason must be at least 10 characters long')
    }

    // 查找用户
    const user = await prisma.developer.findUnique({
      where: { id: userId }
    })

    if (!user) {
      throw new NotFoundError('User not found')
    }

    if (user.role === 'admin') {
      throw new AuthorizationError('Cannot suspend admin users')
    }

    if (user.status === 'suspended') {
      throw new ConflictError('User is already suspended')
    }

    // 更新用户状态
    await prisma.$transaction(async (tx) => {
      // 更新用户状态
      await tx.developer.update({
        where: { id: userId },
        data: {
          status: 'suspended',
          updatedAt: new Date()
        }
      })

      // 记录审计日志
      await tx.auditLog.create({
        data: {
          userId: adminId,
          action: 'user_suspended',
          resourceType: 'user',
          resourceId: userId,
          oldValues: { status: user.status },
          newValues: {
            status: 'suspended',
            reason: reason.trim()
          }
        }
      })
    })

    // 清除相关缓存
    await this.clearAdminCache()
  }

  // 恢复用户
  async restoreUser(adminId: string, userId: string): Promise<void> {
    // 验证管理员权限
    await this.validateAdminPermission(adminId)

    // 查找用户
    const user = await prisma.developer.findUnique({
      where: { id: userId }
    })

    if (!user) {
      throw new NotFoundError('User not found')
    }

    if (user.status !== 'suspended') {
      throw new ValidationError('User is not suspended')
    }

    // 更新用户状态
    await prisma.$transaction(async (tx) => {
      // 更新用户状态为活跃
      await tx.developer.update({
        where: { id: userId },
        data: {
          status: 'active',
          updatedAt: new Date()
        }
      })

      // 记录审计日志
      await tx.auditLog.create({
        data: {
          userId: adminId,
          action: 'user_restored',
          resourceType: 'user',
          resourceId: userId,
          oldValues: { status: 'suspended' },
          newValues: { status: 'active' }
        }
      })
    })

    // 清除相关缓存
    await this.clearAdminCache()
  }

  // 获取审计日志
  async getAuditLogs(page = 1, limit = 50, filters?: {
    action?: string
    resourceType?: string
    userId?: string
    startDate?: Date
    endDate?: Date
  }): Promise<{
    logs: AuditLogEntry[]
    pagination: { page: number; limit: number; total: number; totalPages: number }
  }> {
    const offset = (page - 1) * limit

    // 构建查询条件
    const where: any = {}

    if (filters?.action) {
      where.action = filters.action
    }

    if (filters?.resourceType) {
      where.resourceType = filters.resourceType
    }

    if (filters?.userId) {
      where.userId = filters.userId
    }

    if (filters?.startDate || filters?.endDate) {
      where.createdAt = {}
      if (filters.startDate) {
        where.createdAt.gte = filters.startDate
      }
      if (filters.endDate) {
        where.createdAt.lte = filters.endDate
      }
    }

    const [logs, total] = await Promise.all([
      prisma.auditLog.findMany({
        where,
        include: {
          user: {
            select: {
              username: true,
              email: true
            }
          }
        },
        orderBy: { createdAt: 'desc' },
        skip: offset,
        take: limit
      }),
      prisma.auditLog.count({ where })
    ])

    const formattedLogs: AuditLogEntry[] = logs.map(log => ({
      id: log.id,
      action: log.action,
      resourceType: log.resourceType || undefined,
      resourceId: log.resourceId || undefined,
      oldValues: log.oldValues || undefined,
      newValues: log.newValues || undefined,
      ipAddress: log.ipAddress || undefined,
      userAgent: log.userAgent || undefined,
      user: log.user || undefined,
      createdAt: log.createdAt
    }))

    return {
      logs: formattedLogs,
      pagination: {
        page,
        limit,
        total,
        totalPages: Math.ceil(total / limit)
      }
    }
  }

  // 清除管理员相关缓存
  private async clearAdminCache(): Promise<void> {
    const cacheKeys = [
      'admin:stats',
      'admin:pending-plugins'
    ]

    for (const key of cacheKeys) {
      await cache.del(key)
    }
  }
}
